home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 July: Mac OS SDK / Dev.CD Jul 96 SDK / Dev.CD Jul 96 SDK1.toast / Development Kits (Disc 1) / Apple Game Sprockets / Examples / DroneZone / DZInput.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-05-16  |  7.5 KB  |  327 lines  |  [TEXT/CWIE]

  1. /*
  2.  *    File:        DZInput.c
  3.  *    Author:        Dan Venolia
  4.  *
  5.  *    Contents:    Handles input devices.
  6.  *
  7.  *    Copyright © 1996 Apple Computer, Inc.
  8.  */
  9.  
  10. #include <TextUtils.h>
  11.  
  12. #include "InputSprocket.h"
  13. #include "InputSprocketDriver.h"  //• TEMPORARY
  14.  
  15. #include "DZGame.h"
  16. #include "DZInput.h"
  17. #include "DZResource.h"
  18.  
  19. #define USE_MOUSE_AND_KEYBOARD 1
  20.  
  21. enum {
  22.     kDeviceList_COUNT        = 100
  23. };
  24.  
  25. enum {
  26.     kElement_Fire,
  27.     kElement_Pause,
  28.     kElement_ShowHUD,
  29.     kElement_ShowFPS,
  30.     kElement_LIST_COUNT,  // only elements above this line go onto the event list
  31.     kElement_Turn = kElement_LIST_COUNT,
  32.     kElement_COUNT
  33. };
  34.  
  35.  
  36. static Boolean                    gInputActive = false;
  37. static ISpElementListReference    gInputEventList = NULL;
  38. static ISpElementReference        gInputElement[kElement_COUNT] = {NULL, NULL, NULL, NULL, NULL};
  39.  
  40.  
  41. /* =============================================================================
  42.  *        Input_Init (external)
  43.  *
  44.  *    Initializes the Input stuff.
  45.  * ========================================================================== */
  46. void Input_Init(
  47.     void)
  48. {
  49.     UInt32                        count;
  50.     ISpDeviceReference            deviceList[kDeviceList_COUNT];
  51.     
  52.     ISpNeed                        needs[kElement_COUNT] =
  53.     {
  54.         { "\p", kIconSuiteID_Fire,        kISpElementKind_Button,        kISpElementLabel_Fire,    0    },
  55.         { "\p", kIconSuiteID_Pause,     kISpElementKind_Button,        kISpElementLabel_Start,    0    },
  56.         { "\p", kIconSuiteID_ShowHUD,    kISpElementKind_Button,        kISpElementLabel_None,    0    },
  57.         { "\p", kIconSuiteID_ShowFPS,    kISpElementKind_Button,        kISpElementLabel_None,    0    },
  58.         { "\p",    kIconSuiteID_Turn,         kISpElementKind_Movement,    kISpElementLabel_None,    0    },
  59.     };
  60.     
  61.     // Get the names for the needs
  62.     GetIndString(needs[kElement_Fire].name,        kStrListID_NeedsNames,    kElement_Fire+1);
  63.     GetIndString(needs[kElement_Pause].name,    kStrListID_NeedsNames,    kElement_Pause+1);
  64.     GetIndString(needs[kElement_ShowHUD].name,    kStrListID_NeedsNames,    kElement_ShowHUD+1);
  65.     GetIndString(needs[kElement_ShowFPS].name,    kStrListID_NeedsNames,    kElement_ShowFPS+1);
  66.     GetIndString(needs[kElement_Turn].name,        kStrListID_NeedsNames,    kElement_Turn+1);
  67.     
  68.     #if USE_MOUSE_AND_KEYBOARD
  69.         // Enable the mouse
  70.         
  71.         // NOTE: This is not the correct way to handle the list count thing.  We
  72.         // should actually call once with NULL for the device list, malloc a list of
  73.         // that size, and call again.
  74.         
  75.         ISpDevices_ExtractByClass(
  76.                 kISpDeviceClass_Mouse,
  77.                 kDeviceList_COUNT,
  78.                 &count,
  79.                 deviceList);
  80.         
  81.         if (count > kDeviceList_COUNT)
  82.         {
  83.             count = kDeviceList_COUNT;
  84.         }
  85.         
  86.         ISpDevices_Activate(
  87.                 count,
  88.                 deviceList);
  89.         
  90.         // Enable the keyboard
  91.         ISpDevices_ExtractByClass(
  92.                 kISpDeviceClass_Keyboard,
  93.                 kDeviceList_COUNT,
  94.                 &count,
  95.                 deviceList);
  96.         
  97.         if (count > kDeviceList_COUNT)
  98.         {
  99.             count = kDeviceList_COUNT;
  100.         }
  101.         
  102.         ISpDevices_Activate(
  103.                 count,
  104.                 deviceList);
  105.     #endif
  106.     
  107.     // Set our virtual elements
  108.       ISpElement_NewVirtualFromNeeds(
  109.               kElement_COUNT,
  110.               needs,
  111.               gInputElement,
  112.               0);
  113.     
  114.     // Autoconfigure our virtual elements based on our needs
  115.     ISpInit(
  116.             kElement_COUNT,
  117.             needs,
  118.             gInputElement,
  119.             ' dz ',
  120.             '????',  // could use this as versioning on the needs
  121.             0,
  122.             0,
  123.             0);
  124.       
  125.       // Build our list of elements, which we'll poll for events
  126.     ISpElementList_New(
  127.             kElement_LIST_COUNT,
  128.             gInputElement,
  129.             &gInputEventList,
  130.             0);
  131.     
  132.     //• SHOULD construct our element list by hand -- add the refcons one-by-one
  133.     
  134.     // Start off suspended (because the game is stopped)
  135.     ISpSuspend();
  136.     
  137.     #if 1  //• TEMPORARY
  138.     {
  139.         // Initialize the virtual movement element to (mid,mid)
  140.         ISpMovementData data;
  141.         AbsoluteTime time;
  142.         
  143.         data.xAxis = kISpAxisMiddle;
  144.         data.yAxis = kISpAxisMiddle;
  145.         data.direction = kISpPadIdle;
  146.         
  147.         time.hi = 0;
  148.         time.lo = 0;
  149.         
  150.         ISpElement_PushComplexData(gInputElement[kElement_Turn], sizeof(ISpMovementData), &data, &time);
  151.     }
  152.     #endif
  153. }
  154.  
  155.  
  156. /* =============================================================================
  157.  *        Input_Exit (external)
  158.  *
  159.  *    Prepares for exit.
  160.  * ========================================================================== */
  161. void Input_Exit(
  162.     void)
  163. {
  164.     if (gInputEventList != NULL)
  165.     {
  166.         ISpElementList_Dispose(gInputEventList);
  167.         gInputEventList = NULL;
  168.     }
  169.     
  170.      ISpStop();
  171.      
  172.     ISpElement_DisposeVirtual(kElement_COUNT, gInputElement);
  173. }
  174.  
  175.  
  176. /* =============================================================================
  177.  *        Input_Configure (external)
  178.  *
  179.  *    Show the configuration dialog.
  180.  * ========================================================================== */
  181. void Input_Configure(
  182.     void)
  183. {
  184.     #if 0
  185.         //••• THIS IS THE WAY THIS SHOULD READ
  186.          ISpConfigure(NULL);
  187.     #else
  188.         //••• THIS IS A TEMPORARY HACK
  189.         if (gInputActive)
  190.         {
  191.              ISpConfigure(NULL);
  192.         }
  193.         else
  194.         {
  195.             ISpResume();
  196.              ISpConfigure(NULL);
  197.              ISpSuspend();
  198.         }
  199.     #endif
  200. }
  201.  
  202.  
  203. /* =============================================================================
  204.  *        Input_GetState (external)
  205.  *
  206.  *    This routine handles the elements that are polled.  It returns in outXTurn
  207.  *    and outYTurn the "turn" controls in the ±1 range.
  208.  * ========================================================================== */
  209. void Input_GetState(
  210.     float*                outXTurn,
  211.     float*                outYTurn)
  212. {
  213.     ISpMovementData        movementData;
  214.     float                xTurn;
  215.     float                yTurn;
  216.     
  217.     // Get the data
  218.     ISpElement_GetComplexState(
  219.             gInputElement[kElement_Turn],
  220.             sizeof(ISpMovementData),
  221.             &movementData);
  222.     
  223.     // Turn 'em into ±1 float range
  224.     xTurn = movementData.xAxis;
  225.     xTurn -= kISpAxisMiddle;
  226.     xTurn /= kISpAxisMaximum-kISpAxisMiddle;
  227.     
  228.     yTurn = movementData.yAxis;
  229.     yTurn -= kISpAxisMiddle;
  230.     yTurn /= kISpAxisMaximum-kISpAxisMiddle;
  231.     
  232.     // Return the values
  233.     *outXTurn = xTurn;
  234.     *outYTurn = yTurn;
  235. }
  236.  
  237.  
  238. /* =============================================================================
  239.  *        Input_GetEvent (external)
  240.  *
  241.  *    This routine handles the elements that are event-based.  It returns an
  242.  *    event code indicating which button has gone down.  Note that we ignore
  243.  *    button-up transitions.  Should be called repeatedly until it return
  244.  *    kInputEvent_None.
  245.  * ========================================================================== */
  246. TInputEvent Input_GetEvent(
  247.     void)
  248. {
  249.     TInputEvent            result = kInputEvent_None;
  250.     ISpElementEvent        event;
  251.     Boolean                gotEvent;
  252.     
  253.     ISpElementList_GetNextEvent(gInputEventList, sizeof(event), &event, &gotEvent);
  254.     
  255.     if (gotEvent && event.data != 0)
  256.     {
  257.         #if 0
  258.             //••• RESTORE THIS WHEN WE GET THE REFCON SET
  259.             result = event->refCon;
  260.         #else
  261.             if (event.element == gInputElement[kElement_Fire])
  262.             {
  263.                 result = kInputEvent_Fire;
  264.             }
  265.             else if (event.element == gInputElement[kElement_Pause])
  266.             {
  267.                 result = kInputEvent_Pause;
  268.             }
  269.             else if (event.element == gInputElement[kElement_ShowHUD])
  270.             {
  271.                 result = kInputEvent_ShowHUD;
  272.             }
  273.             else if (event.element == gInputElement[kElement_ShowFPS])
  274.             {
  275.                 result = kInputEvent_ShowFPS;
  276.             }
  277.         #endif
  278.     }
  279.     
  280.     return result;
  281. }
  282.  
  283.  
  284. /* =============================================================================
  285.  *        Input_Activate (external)
  286.  *
  287.  *    On deactivation, we suspend InputSprocket.  On activation we resume it and
  288.  *    flush the event queue.  We only allow activation when the game is in "Play"
  289.  *    state.
  290.  * ========================================================================== */
  291. void Input_Activate(
  292.     Boolean                inActivate)
  293. {
  294.     Boolean                doActivate;
  295.     
  296.     doActivate = inActivate;
  297.     if (doActivate && Game_GetState() != kGameState_Playing)
  298.     {
  299.         doActivate = false;
  300.     }
  301.     
  302.     if (gInputActive != doActivate)
  303.     {
  304.         gInputActive = doActivate;
  305.         
  306.          if (gInputActive)
  307.          {
  308.              #if USE_MOUSE_AND_KEYBOARD
  309.                  HideCursor();
  310.              #endif
  311.              
  312.              ISpResume();
  313.              ISpElementList_Flush(gInputEventList);
  314.          }
  315.          else
  316.          {
  317.              ISpSuspend();
  318.              
  319.              #if USE_MOUSE_AND_KEYBOARD
  320.                  ShowCursor();
  321.              #endif
  322.          }
  323.     }
  324. }
  325.  
  326.  
  327.